<template>
    <div class="login-container">
        <div class="login-box">
            <!-- ref：必须属性 后期方便el-from组件的获取使用 -->
            <!-- :model和v-model没有关系 是对表单全部数据进行绑定的 -->
            <!-- lebal-width：非必须属性 -->
            <el-form ref="loginformRef" :model="loginForm" :rules="loginformRules">
                <img src="./logo_index.png">
                <!-- 每个表单域都需要el-form-item组件进行圈选 -->
                <!-- prop:让验证规则和当前组件联系起来 名称必须和表单对象名称一致loginForm.mobile -->
                <!-- 手机号码 -->
                <el-form-item prop="mobile">
                    <el-input prefix-icon="iconfont icon-shouji" v-model="loginForm.mobile" placeholder="请输入手机号码"></el-input>
                </el-form-item>
                <!-- 验证码 -->
                <el-form-item prop="code">
                    <el-input prefix-icon="iconfont icon-verify-fill" v-model="loginForm.code" placeholder="验证码"></el-input>
                    <!-- <i slot="prefix" class="iconfont icon-shouji"></i> -->
                </el-form-item>
                <!-- 协议 -->
                <el-form-item style="text-align: left;" prop="xieyi">
                    <el-checkbox v-model="loginForm.xieyi"></el-checkbox>
                    <span>我已阅读并同意用户协议和隐私条款</span>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button :loading="flag"
                      :disabled="flag"
                      type="primary"
                      style="width:100%"
                      @click="login()">登录
                    </el-button>
                </el-form-item>
            </el-form>
        </div>
    </div>
</template>

<script>
// 引入极验的js文件
// 改js文件内没有export default导出 所以不用名称接收
import '@/assets/js/gt.js'
// 引入图标iconfont文件
import '@/assets/iconfont/iconfont.css'
export default {
  data () {
    // 协议自定义验证
    // rule:当前项目校验规则 一般不用
    // value：当前项目的值
    // callback：验证成功或失败都要执行
    var Check = function (rule, value, callback) {
      if (value) {
        callback()
      } else {
        callback(new Error('请选择已阅读'))
      }
    }
    return {
      // 极验窗口对象
      ctaObj: null,
      // 登录按钮的加载和禁选模式默认不开启
      flag: false,
      // 登陆表单以及内部属性值
      loginForm: {
        mobile: '13323332333',
        code: '246810',
        xieyi: true
      },
      // 登录检验 [{规则},{规则},{规则}]
      loginformRules: {
        mobile: [
          { required: true, message: '请输入手机号' },
          { pattern: /^1[35789]\d{9}$/, message: '手机号码格式不对' }
        ],
        code: [
          { required: true, message: '验证码必填' }
        ],
        xieyi: [
          { validator: Check, trigger: 'blur' }
        ]
      }
    }
  },

  methods: {
    login () {
      // valid 参数是布尔值 表示校验是否成功
      // 获得form组件对象 this.$refs.ref值 ref值即el-form 组件的ref的属性值
      // form组件对象.validate(回调函数)
      this.$refs.loginformRef.validate((valid) => {
        // 验证成功
        if (valid) {
          // 如果窗口存在则显示
          if (this.ctaObj) {
            return this.ctaObj.verify()
          }
          // 登录按钮开启加载和禁选模式
          this.flag = true
          // 表单验证成功
          // A.利用极验进行人机交互验证
          let pro = this.$http.get(`/captchas/${this.loginForm.mobile}`)
          pro
            .then(result => {
              // axios请求成功
              // 生成极验验证窗口 initGeetest()是极验里面的方法 里面的属性名不要更改
              // 接口中的属性名和initGeetest方法中的属性名一致 利用解构赋值来进行赋值
              let { data } = result.data
              window.initGeetest({
                // 以下配置参数来自服务端 SDK
                gt: data.gt,
                challenge: data.challenge,
                offline: !data.success,
                new_captcha: true,
                // 隐藏按钮 通过登录按钮激活
                product: 'bind'
              }, (captchaObj) => {
                captchaObj.onReady(() => {
                  // 验证码ready之后才能调用verify方法显示验证码
                  // 生成窗口
                  captchaObj.verify()
                  // 为避免窗口重复创建导致变慢 把窗口对象存储到data成员ctaObj中
                  this.ctaObj = captchaObj
                  // 显示极验验证的滑动窗口后登录按钮回复禁用等待
                  this.flag = false
                }).onSuccess(() => {
                  // 滑动正确 登陆后台系统
                  this.loginAct()
                }).onError(() => {
                  // your code
                })
              })
            })
            .catch(err => {
              // this.$message.error() 饿了么组件方法
              return this.$message.error('极验验证错误:' + err)
            })
        }
      })
    },
    // 极验 账号真实性验证 成功后登陆后台页面
    loginAct () {
      // axios真实性验证
      // this.$http 在main.js已经注册过 可以用来获得vue的实例对象 等于axios
      // authorizations接口号 文档里有
      let pro = this.$http.post('authorizations', this.loginForm) // mobile: this.loginForm.mobile,code: this.loginForm.code
      pro.then(result => {
        if (result.data.message === 'OK') {
          // 将服务端返回对象信息以字符串形式存到 SessionStorage 用来验证是否登录
          // 然后在路由中设置守卫
          window.sessionStorage.setItem('userinfo', JSON.stringify(result.data.data))
          this.$router.push('/home')
        }
      })
        .catch(err => {
          // return this.$message.error('错了哦，这是一条错误消息' + err)
          // 另一种设置方式 可以设置提示框的停留时间
          return this.$message({ type: 'err', message: '用户名或密码错误' + err, duration: 3000 })
        })
    }
  }
}
</script>

<style lang="less" scoped>
    .login-container{
        background-color: gray;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        background-image: url('./login_bg.jpg');
        background-size: cover;
        .login-box{
            width: 400px;
            height: 340px;
            background-color: #fff;
            display: flex;
            justify-content: center;
            align-items: center;
            text-align: center;
            img{
                width: 50%;
                margin-bottom: 10px;
            }
        }
        .el-form{
            width: 80%;
            .el-button{
                margin-top: 10px;
            }
        }
    }
</style>
